package com.alibaba.citrus.cr.mn.order.center.facade.function.convert;

import com.alibaba.citrus.cr.common.constant.OrderFeaturesKey;
import com.alibaba.citrus.cr.common.enums.ordercenter.FulfillmentTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderReasonEnum;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.SetOrderTag;
import com.alibaba.citrus.cr.mn.order.center.facade.function.dataobject.AtomOrderDO;
import com.alibaba.cloud.retail.delivery.api.model.delivery.enums.OrderTagEnum;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.epoch.app.crb2btradecenter.domain.order.model.Order;
import com.epoch.app.crb2btradecenter.domain.orderline.model.OrderLine;
import com.epoch.app.crb2btradecenter.enums.OrderStatus;
import com.epoch.app.mnordercenter.model.dto.ReturnOrderAtomCreateRequest;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomCreateLineRequest;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.common.constant.OrderFeaturesKey.KA_AREA;
import static com.alibaba.citrus.cr.common.constant.OrderFeaturesKey.KA_SYSTEM;

/**
 * @author dongju
 * @ClassName ReturnOrderAtomCreateRequestToAtomOrderDOConvertor
 */
public class ReturnOrderAtomCreateRequestToAtomOrderDOConvertor  {

    public static List<AtomOrderDO> convert(List<ReturnOrderAtomCreateRequest> requestList) {
        return Optional.ofNullable(requestList).orElse(Lists.newArrayList()).stream().map(request -> {
            if (Objects.isNull(request.getIsSubmit())) {
                request.setIsSubmit(Boolean.TRUE);
            }

            AtomOrderDO atomOrderDO = new AtomOrderDO();
            atomOrderDO.setOrder(convert(request));
            atomOrderDO.setOrderLines(convertOrderLine(request.getOrderDetails(), atomOrderDO.getOrder()));
            atomOrderDO.setAutoSubmit(request.getIsSubmit());

            for (OrderLine orderLine : atomOrderDO.getOrderLines()) {
                orderLine.setCreatorId(atomOrderDO.getOrder().getCreator());
                orderLine.setCreatorName(atomOrderDO.getOrder().getCreatorName());
                orderLine.setStatus(atomOrderDO.getOrder().getStatus());
                refreshUserInfo4Features(orderLine, request.getCreatorCode(), request.getCreatorName());
            }
            return atomOrderDO;
        }).collect(Collectors.toList());
    }

    public static Order convert(ReturnOrderAtomCreateRequest request){
        Order order = new Order();
        BeanUtils.copyProperties(request, order);

        order.setBusinessType(StringUtils.isBlank(request.getBusinessType()) ? null : Integer.parseInt(request.getBusinessType()));
        order.setBisUnitCode(request.getBusinessUnitCode());
        order.setBisUnitName(request.getBusinessUnitName());
        order.setCreator(request.getCreatorCode());
        order.setOrderType(request.getSalesOrderType());
        order.setOrderTypeName(request.getSalesOrderTypeName());
        order.setChannelCode(request.getBusinessChannel());
        order.setChannelName(request.getBusinessChannelName());
        order.setTransportModeCode(request.getDeliveryMethodCode());
        order.setTransportModeName(request.getDeliveryMethodName());
        order.setOrganizationCode(request.getSalesOrganizationCode());
        order.setOrganizationName(request.getSalesOrganizationName());
        order.setReceiveAddressCode(request.getShipToPartyCode());
        order.setReceiveDetailAddress(request.getShipToPartyName());
        order.setDepartmentName(request.getSalesDepartmentName());
        order.setDepartmentCode(request.getSalesDepartmentCode());
        order.setSaleChannelName(request.getSalesChannelName());
        order.setSaleChannelCode(request.getSalesChannelCode());
        order.setRemark(request.getNote());
        order.setCostCenter(request.getCostCenterCode());
        order.setCustomerPurchaseDate(DateUtils.string2Date(request.getCustomerPurchaseDate()));//客户采购订单日期
        order.setCustomerExpectDate(DateUtils.string2Date(request.getExpectedDeliveryDate()));//期望日期
        order.setCustomerReferenceNo(request.getCustomerPurchaseOrderNo());//客户采购订单号
        if(StringUtils.isNotBlank(request.getOrderReasonCode())) {
            order.setCreateReason(request.getOrderReasonCode());
            SalesOrderReasonEnum salesOrderReasonEnum= SalesOrderReasonEnum.of(request.getOrderReasonCode().trim());
            if(salesOrderReasonEnum!=null){
                order.setCreateReasonName(salesOrderReasonEnum.getDesc());
            }
        }
        // TODO 此处后续 若移除主单的逻辑仓 可能导致单据推送SAP失败
        SalesOrderAtomCreateLineRequest salesOrderAtomCreateLineRequest = request.getOrderDetails().get(0);
        String shippingWarehouseCode = salesOrderAtomCreateLineRequest.getShippingWarehouseCode();
        String shippingWarehouseName = salesOrderAtomCreateLineRequest.getShippingWarehouseName();
        order.setWareHouseCode(shippingWarehouseCode);
        order.setWareHouseName(shippingWarehouseName);

        order.setReceiveWareHouseCode(salesOrderAtomCreateLineRequest.getTxWarehouseCode());
        order.setReceiveWareHouseName(salesOrderAtomCreateLineRequest.getTxWarehouseName());
        order.setReceiveFactoryCode(salesOrderAtomCreateLineRequest.getTxFactoryCode());
        order.setReceiveStockCode(salesOrderAtomCreateLineRequest.getTxStockCode());

        // 状态确认 默认待提交，若IS-Submit=true，则为已推送 推送SAP
        order.setStatus(BooleanUtils.isTrue(request.getIsSubmit()) ? OrderStatus.PUSHING.getCode() : OrderStatus.BEFORE_SUBMIT.getCode());
        // 当前单据都是 return 订单
        order.setOrderTag(SetOrderTag.RETURN);
        //发货状态是 待发货
        if (OrderCategoryEnum.GROUP.equals(OrderCategoryEnum.of(order.getOrderCategoryCode())) && FulfillmentTypeEnum.returnCodes().contains(order.getFulfillmentTypeCode())) {
            order.setSubStatus(String.valueOf(OrderStatus.BEFORE_DELIVERY.getCode()));
        }
        order.setCustomerGroupName(request.getCustomerGroupName());

        order.setOrderChannelCode(request.getOrderChannelCode());
        order.setCostCenterName(request.getCostCenterName());
        order.setFulfillmentTypeCode(request.getFulfillmentTypeCode());
        order.setAutoFulfillment(request.getAutoFulfillment());
        order.setFulfillmentPriority(request.getFulfillmentPriority());
        if (CollectionUtils.isNotEmpty(request.getOrderBizTag())){
            order.setOrderBizTag(request.getOrderBizTag().stream().collect(Collectors.joining(",")));
        }

        refreshUserInfo4Features(order, request);
        return order;
    }

    static void refreshUserInfo4Features(Order order, ReturnOrderAtomCreateRequest request) {
        Map<String, String> featuresMap = JSONObject.parseObject(order.getFeatures(), new TypeReference<Map<String, String>>() {});
        featuresMap = Optional.ofNullable(featuresMap).orElse(Maps.newHashMap());
        String userCode = request.getCreatorCode();
        String userName = request.getCreatorName();
        featuresMap.put("creatorCode", userCode);
        featuresMap.put("creatorName", userName);
        featuresMap.put(KA_SYSTEM, request.getKaSystem());
        featuresMap.put(KA_AREA, request.getKaArea());
//        featuresMap.put("modifierCode", userCode);
//        featuresMap.put("modifierName", userName);
        order.setCreatorCode(userCode);
        order.setCreatorName2(userName);

        order.setFeatures(JSONObject.toJSONString(featuresMap));
    }

    static void refreshUserInfo4Features(OrderLine orderLine, String userCode, String userName) {
        Map<String, String> lineFeaturesMap = JSONObject.parseObject(orderLine.getFeatures(), new TypeReference<Map<String, String>>() {});
        lineFeaturesMap = Optional.ofNullable(lineFeaturesMap).orElse(Maps.newHashMap());
        lineFeaturesMap.put("creatorCode", userCode);
        lineFeaturesMap.put("creatorName", userName);
//        lineFeaturesMap.put("modifierCode", userCode);
//        lineFeaturesMap.put("modifierName", userName);

        orderLine.setFeatures(JSONObject.toJSONString(lineFeaturesMap));
    }

    /**明细单行号 布进器**/
    private static final Integer Order_Line_Step = 10;
    public static List<OrderLine> convertOrderLine(List<SalesOrderAtomCreateLineRequest> orderDetails, Order order) {

        AtomicReference<Integer> num = new AtomicReference<>(0);

        return Optional.ofNullable(orderDetails).orElse(Lists.newArrayList()).stream().map(lineRequest -> {
            // 循环行数 递增
            num.set(num.get() + 1);

            OrderLine lineSDO = new OrderLine();
            BeanUtils.copyProperties(lineRequest, lineSDO);

            // 明细单行号 当前 * 步长
            lineSDO.setSerialNumber(String.valueOf(num.get() * Order_Line_Step));
            lineSDO.setScItemId(lineRequest.getProductCode());
            lineSDO.setScItemTitle(lineRequest.getProductName());
            lineSDO.setQuantity(Integer.parseInt(lineRequest.getProductQuantity()));
            lineSDO.setSaleUnit(lineRequest.getSalesUnitCode());
            lineSDO.setSaleUnitName(lineRequest.getSalesUnitName());
            lineSDO.setInventoryUnitCode(lineRequest.getStockUnitCode());
            lineSDO.setInventoryUnit(lineRequest.getStockUnitName());
            lineSDO.setShouldPayFee(lineRequest.getTotalAmount());// TODO 应付金额
            lineSDO.setUnitConvert(lineRequest.getUnitConversionRelationship());
            lineSDO.setProductationTime(DateUtils.string2Date(lineRequest.getProductionDate()));
            lineSDO.setRemark(lineRequest.getNote());
            lineSDO.setScItemOutCode(lineRequest.getProductCode());
            lineSDO.setActualPaidFee(lineRequest.getActivityTotalAmount());
            lineSDO.setOrderLineTag(SetOrderTag.RETURN);
            lineSDO.setReceiveWarehouseCode(lineRequest.getTxWarehouseCode());
            lineSDO.setReceiveWarehouseOutCode(lineRequest.getTxWarehouseCode());
            lineSDO.setReceiveWarehouseName(lineRequest.getTxWarehouseName());
            lineSDO.setReceiveFactoryCode(lineRequest.getTxFactoryCode());
            lineSDO.setReceiveFactoryName(lineRequest.getTxFactoryName());
            lineSDO.setReceiveStockCode(lineRequest.getTxStockCode());
            lineSDO.setReceiveStockName(lineRequest.getTxStockName());
            lineSDO.setProductationTime(DateUtils.string2Date(lineRequest.getProductionDate()));
            //发货状态是 待发货
            if (OrderCategoryEnum.GROUP.equals(OrderCategoryEnum.of(order.getOrderCategoryCode())) && FulfillmentTypeEnum.returnCodes().contains(order.getFulfillmentTypeCode())) {
                lineSDO.setSubStatus(String.valueOf(OrderStatus.BEFORE_DELIVERY.getCode()));
            }

            Map<String, String> features = Maps.newHashMap();
            if(StringUtils.isNotBlank(lineRequest.getManualPrice())) {
                lineSDO.setManualPrice(lineRequest.getManualPrice());
                features.put(OrderFeaturesKey.MANUAL_PRICE, lineRequest.getManualPrice());//手工单价
            }
            if(StringUtils.isNotBlank(lineRequest.getManualTotalAmount())) {
                features.put(OrderFeaturesKey.MANUAL_TOTAL_AMOUNT, lineRequest.getManualTotalAmount());//手工总金额
                lineSDO.setManualTotalAmount(lineRequest.getManualTotalAmount());
            }
            if (StringUtils.isNotBlank(lineRequest.getInvoiceNo())){
                features.put(OrderFeaturesKey.INVOICE_NO,lineRequest.getInvoiceNo()); //发票号
            }
            if (StringUtils.isNotBlank(lineRequest.getInvoiceLineNo())){
                features.put(OrderFeaturesKey.INVOICE_LINE_NO,lineRequest.getInvoiceLineNo()); //发票行号
            }
            lineSDO.setFeatures(JSONObject.toJSONString(features));

            return lineSDO;
        }).collect(Collectors.toList());
    }

}
